package the.workshop.bu.service.support;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import the.workshop.bu.entity.Product;
import the.workshop.bu.entity.ProductArea;
import the.workshop.bu.entity.ProductRule;
import the.workshop.bu.mapper.ProductAreaMapper;
import the.workshop.bu.mapper.ProductMapper;
import the.workshop.bu.mapper.ProductRuleMapper;
import the.workshop.bu.service.dto.ProductSearchConditionDTO;
import the.workshop.bu.service.dto.ProductSearchResultDTO;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class ProductSearchSupport {

    @Resource
    private ProductMapper productMapper;

    @Resource
    private ProductRuleMapper productRuleMapper;

    @Resource
    private ProductAreaMapper productAreaMapper;

    public List<ProductSearchResultDTO> search(ProductSearchConditionDTO dto) {
        Set<Integer> productIdSet = new HashSet<>();

        List<ProductRule> productRuleList = productRuleMapper.selectList(new LambdaQueryWrapper<ProductRule>()
                .in(ProductRule::getRuleId, dto.getRuleIdList()));
        if (!CollectionUtils.isEmpty(productRuleList)) {
            Map<Integer, List<ProductRule>> productRuleGrouping = productRuleList.stream().collect(Collectors.groupingBy(ProductRule::getProductId));
            for (Map.Entry<Integer, List<ProductRule>> entry : productRuleGrouping.entrySet()) {
                if (entry.getValue().size() == dto.getRuleIdList().size()) {
                    productIdSet.add(entry.getKey());
                }
            }
        }

        List<ProductArea> productAreaList = productAreaMapper.selectList(new LambdaQueryWrapper<ProductArea>()
                .eq(ProductArea::getProvinceId, dto.getProvinceId())
                .eq(ProductArea::getCityId, dto.getCityId())
        );
        if (!CollectionUtils.isEmpty(productAreaList)) {
            productAreaList.forEach(it -> productIdSet.add(it.getProductId()));
        }

        if (CollectionUtils.isEmpty(productIdSet)) {
            return null;
        }

        List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>()
                .in(Product::getId, productIdSet)
                .orderByDesc(Product::getSerial).orderByAsc(Product::getName)
        );
        if (CollectionUtils.isEmpty(productList)) {
            return null;
        }

        return productList.stream().map(this::convertOf).collect(Collectors.toList());
    }

    private ProductSearchResultDTO convertOf(Product source) {
        ProductSearchResultDTO target = new ProductSearchResultDTO();
        target.setProductId(source.getId());
        target.setProductName(source.getName());
        target.setProductLogo(source.getLogo());
        target.setInterestYear(source.getInterestYear());
        target.setQuota(source.getQuota());
        target.setLegalPersonAgeStart(source.getLegalPersonAgeStart());
        target.setLegalPersonAgeEnd(source.getLegalPersonAgeEnd());
        return target;
    }
}
